From 3b1faf84237d3d1aa631b639b28ed096b49351b8 Mon Sep 17 00:00:00 2001 From: "smh22@labyrinth.cl.cam.ac.uk" Date: Wed, 5 Nov 2003 15:12:12 +0000 Subject: [PATCH] bitkeeper revision 1.564 (3fa9134cYyjxglAlh2gjmCiQ901Z8g) misc vbd tweaks tidies and fixes --- tools/internal/dom0_defs.h | 5 -- tools/internal/xi_phys_grant.c | 13 ++-- xen/drivers/block/xen_vbd.c | 20 +++-- xen/drivers/ide/ide-xeno.c | 2 +- xen/drivers/scsi/sd.c | 2 +- xen/include/hypervisor-ifs/block.h | 29 +++---- xen/include/hypervisor-ifs/vbd.h | 48 ++++-------- xen/include/xeno/vbd.h | 19 +---- .../arch/xeno/drivers/block/xl_block.c | 9 +-- .../arch/xeno/drivers/block/xl_vbd.c | 75 +++++++++---------- 10 files changed, 89 insertions(+), 133 deletions(-) diff --git a/tools/internal/dom0_defs.h b/tools/internal/dom0_defs.h index 40181db15a..0c0c4080dd 100644 --- a/tools/internal/dom0_defs.h +++ b/tools/internal/dom0_defs.h @@ -58,11 +58,6 @@ static inline int do_privcmd(unsigned int cmd, unsigned long data) return ret; } -static inline int do_xen_blkmsg(privcmd_blkmsg_t *blkmsg) -{ - return do_privcmd(IOCTL_PRIVCMD_BLKMSG, (unsigned long)blkmsg); -} - static inline int do_xen_hypercall(privcmd_hypercall_t *hypercall) { return do_privcmd(IOCTL_PRIVCMD_HYPERCALL, (unsigned long)hypercall); diff --git a/tools/internal/xi_phys_grant.c b/tools/internal/xi_phys_grant.c index 9267c5f85d..c5a608ce61 100644 --- a/tools/internal/xi_phys_grant.c +++ b/tools/internal/xi_phys_grant.c @@ -26,12 +26,17 @@ int main(int argc, char *argv[]) */ domain = atoi(argv[2]); device = atoi(argv[3]); - /* XXX SMH: hack -- generate device name by addition ptn number */ + /* XXX SMH: hack -- generate device name by addition ptn number */ vdevice = device + atoi(argv[6]); op.cmd = BLOCK_IO_OP_VBD_CREATE; op.u.create_info.domain = domain; op.u.create_info.vdevice = vdevice; + op.u.create_info.mode = 0; + if ( strchr(argv[1], 'r') ) + op.u.create_info.mode |= VBD_MODE_R; + if ( strchr(argv[1], 'w') ) + op.u.create_info.mode |= VBD_MODE_W; ret = do_block_io_op(&op); @@ -49,13 +54,7 @@ int main(int argc, char *argv[]) op.u.add_info.extent.device = device; op.u.add_info.extent.start_sector = atol(argv[4]); op.u.add_info.extent.nr_sectors = atol(argv[5]); - op.u.add_info.extent.mode = 0; - if ( strchr(argv[1], 'r') ) - op.u.add_info.extent.mode |= PHYSDISK_MODE_R; - if ( strchr(argv[1], 'w') ) - op.u.add_info.extent.mode |= PHYSDISK_MODE_W; - ret = do_block_io_op(&op); if(ret < 0) { diff --git a/xen/drivers/block/xen_vbd.c b/xen/drivers/block/xen_vbd.c index dae8e9343a..50e8173d88 100644 --- a/xen/drivers/block/xen_vbd.c +++ b/xen/drivers/block/xen_vbd.c @@ -45,6 +45,7 @@ long vbd_create(vbd_create_t *create_info) new_vbd = kmalloc(sizeof(vbd_t), GFP_KERNEL); new_vbd->vdevice = create_info->vdevice; + new_vbd->mode = create_info->mode; new_vbd->extents = (xen_extent_le_t *)NULL; new_vbd->next = (vbd_t *)NULL; @@ -94,7 +95,6 @@ long vbd_add(vbd_add_t *add_info) xele->extent.device = add_info->extent.device; xele->extent.start_sector = add_info->extent.start_sector; xele->extent.nr_sectors = add_info->extent.nr_sectors; - xele->extent.mode = add_info->extent.mode; xele->next = (xen_extent_le_t *)NULL; if(!v->extents) { @@ -141,6 +141,13 @@ int vbd_translate(phys_seg_t * pseg, int *nr_segs, return -ENODEV; } + if(operation == READ && !VBD_CAN_READ(v)) + return -EACCES; + + if(operation == WRITE && !VBD_CAN_WRITE(v)) + return -EACCES; + + /* Now iterate through the list of xen_extents, working out which should be used to perform the translation. */ sec = pseg->sector_number; @@ -151,12 +158,6 @@ int vbd_translate(phys_seg_t * pseg, int *nr_segs, /* we've got a match! XXX SMH: should deal with situation where we span multiple xe's */ - if(operation == READ && !(x->extent.mode & PHYSDISK_MODE_R)) - return -EACCES; - - if(operation == WRITE && !(x->extent.mode & PHYSDISK_MODE_W)) - return -EACCES; - pseg->dev = x->extent.device; pseg->sector_number += x->extent.start_sector; @@ -189,7 +190,10 @@ void vbd_probe_devices(xen_disk_info_t *xdi, struct task_struct *p) for(i = 0; i < VBD_HTAB_SZ; i++) { for(v = p->vbdtab[i]; v; v = v->next) { xdi->disks[xdi->count].device = v->vdevice; - xdi->disks[xdi->count].type = XD_TYPE_DISK; // always :-) + xdi->disks[xdi->count].info = XD_FLAG_VIRT | XD_TYPE_DISK; + + /* XXX SMH: and now set XD_FLAG_RO if necessary */ + xdi->disks[xdi->count].capacity = 0; for(x = v->extents; x; x = x->next) xdi->disks[xdi->count].capacity += x->extent.nr_sectors; diff --git a/xen/drivers/ide/ide-xeno.c b/xen/drivers/ide/ide-xeno.c index 46213fc1c8..5607164e80 100644 --- a/xen/drivers/ide/ide-xeno.c +++ b/xen/drivers/ide/ide-xeno.c @@ -55,7 +55,7 @@ void ide_probe_devices(xen_disk_info_t* xdi) capacity = current_capacity(drive); xdi->disks[xdi->count].device = device; - xdi->disks[xdi->count].type = type; + xdi->disks[xdi->count].info = type; xdi->disks[xdi->count].capacity = capacity; xdi->count++; diff --git a/xen/drivers/scsi/sd.c b/xen/drivers/scsi/sd.c index eeb1c5aff2..81ef215635 100644 --- a/xen/drivers/scsi/sd.c +++ b/xen/drivers/scsi/sd.c @@ -1353,7 +1353,7 @@ void scsi_probe_devices(xen_disk_info_t *xdi) /* XXX SMH: if make generic, need to properly determine 'type' */ xdi->disks[xdi->count].device = device; - xdi->disks[xdi->count].type = XD_TYPE_DISK; + xdi->disks[xdi->count].info = XD_TYPE_DISK; xdi->disks[xdi->count].capacity = capacity; xdi->count++; diff --git a/xen/include/hypervisor-ifs/block.h b/xen/include/hypervisor-ifs/block.h index a5e05a647a..6d02b4307c 100644 --- a/xen/include/hypervisor-ifs/block.h +++ b/xen/include/hypervisor-ifs/block.h @@ -22,12 +22,6 @@ #define XEN_BLOCK_SPECIAL 4 #define XEN_BLOCK_PROBE 5 /* get config from hypervisor */ #define XEN_BLOCK_DEBUG 6 /* debug */ -#define XEN_BLOCK_VBD_CREATE 7 /* create vbd */ -#define XEN_BLOCK_VBD_DELETE 8 /* delete vbd */ - /* XXX SMH: was 'probe vbd' */ -#define XEN_BLOCK_PHYSDEV_GRANT 10 /* grant access to range of disk blocks */ -#define XEN_BLOCK_PHYSDEV_PROBE 11 /* probe for a domain's physdev accesses */ - /* XXX SMH: was 'probe vbd all' */ /* NB. Ring size must be small enough for sizeof(blk_ring_t) <= PAGE_SIZE. */ #define BLK_RING_SIZE 64 @@ -68,12 +62,10 @@ typedef struct blk_ring_st } blk_ring_t; /* - * - * physical disk (xhd) info, used by XEN_BLOCK_PROBE - * - */ - -#define XEN_MAX_DISK_COUNT 100 + * Information about the real and virtual disks we have; used during + * guest device probing. + */ +#define XEN_MAX_DISK_COUNT 64 /* XXX SMH: below types chosen to align with ide_xxx types in ide.h */ #define XD_TYPE_FLOPPY 0x00 @@ -82,10 +74,19 @@ typedef struct blk_ring_st #define XD_TYPE_OPTICAL 0x07 #define XD_TYPE_DISK 0x20 +#define XD_TYPE_MASK 0x3F +#define XD_TYPE(_x) ((_x) & XD_TYPE_MASK) + +/* The top two bits of the type field encode various flags */ +#define XD_FLAG_RO 0x40 +#define XD_FLAG_VIRT 0x80 +#define XD_READONLY(_x) ((_x) & XD_FLAG_RO) +#define XD_VIRTUAL(_x) ((_x) & XF_FLAG_VIRT) + typedef struct xen_disk { - unsigned short device; /* device number (see top of file) */ - unsigned short type; /* device type, i.e. disk, cdrom, etc */ + unsigned short device; /* device number (opaque 16 bit val) */ + unsigned short info; /* device type and flags */ unsigned long capacity; /* size in terms of #512 byte sectors */ } xen_disk_t; diff --git a/xen/include/hypervisor-ifs/vbd.h b/xen/include/hypervisor-ifs/vbd.h index 31c45bf529..fd50333d7d 100644 --- a/xen/include/hypervisor-ifs/vbd.h +++ b/xen/include/hypervisor-ifs/vbd.h @@ -2,43 +2,13 @@ #define __HYP_IFS_VBD_H__ -#define PHYSDISK_MODE_R 1 -#define PHYSDISK_MODE_W 2 - -#if 0 -typedef struct xp_disk -{ - int mode; /* 0 -> revoke existing access, otherwise bitmask of - PHYSDISK_MODE_? constants */ - int domain; - unsigned short device; /* XENDEV_??? + idx */ - unsigned short partition; /* partition number */ - unsigned long start_sect; - unsigned long n_sectors; -} xp_disk_t; - -#define PHYSDISK_MAX_ACES_PER_REQUEST 254 /* Make it fit in one page */ -typedef struct { - int n_aces; - int domain; - int start_ind; - struct { - unsigned short device; /* XENDEV_??? + idx */ - unsigned short partition; /* partition number */ - unsigned long start_sect; - unsigned long n_sectors; - unsigned mode; - } entries[PHYSDISK_MAX_ACES_PER_REQUEST]; -} physdisk_probebuf_t; -#endif - - -/* Block I/O trap operations and associated structures. +/* + * Block I/O trap operations and associated structures. */ #define BLOCK_IO_OP_SIGNAL 0 /* let xen know we have work to do */ #define BLOCK_IO_OP_RESET 1 /* reset ring indexes on quiescent i/f */ -#define BLOCK_IO_OP_RING_ADDRESS 2 /* returns machine address of I/O ring */ +#define BLOCK_IO_OP_RING_ADDRESS 2 /* returns machine address of I/O ring */ #define BLOCK_IO_OP_VBD_CREATE 3 /* create a new VBD for a given domain */ #define BLOCK_IO_OP_VBD_ADD 4 /* add an extent to a given VBD */ #define BLOCK_IO_OP_VBD_REMOVE 5 /* remove an extent from a given VBD */ @@ -47,18 +17,26 @@ typedef struct { typedef struct _xen_extent { u16 device; + u16 unused; // pad ulong start_sector; ulong nr_sectors; - u16 mode; } xen_extent_t; + + +#define VBD_MODE_R 0x1 +#define VBD_MODE_W 0x2 + +#define VBD_CAN_READ(_v) ((_v)->mode & VBD_MODE_R) +#define VBD_CAN_WRITE(_v) ((_v)->mode & VBD_MODE_R) + typedef struct _vbd_create { unsigned domain; u16 vdevice; + u16 mode; } vbd_create_t; - typedef struct _vbd_add { unsigned domain; u16 vdevice; diff --git a/xen/include/xeno/vbd.h b/xen/include/xeno/vbd.h index 8c4d6b099d..7e9d4c3fa0 100644 --- a/xen/include/xeno/vbd.h +++ b/xen/include/xeno/vbd.h @@ -23,20 +23,20 @@ typedef struct _xen_extent_le { */ typedef struct _vbd { unsigned short vdevice; // what the domain refers to this vbd as + unsigned short mode; // VBD_MODE_{READONLY,READWRITE} xen_extent_le_t *extents; // list of xen_extents making up this vbd struct _vbd *next; // for chaining in the hash table } vbd_t; #define VBD_HTAB_SZ 16 // no. of entries in the vbd hash table. -void xen_vbd_initialize(void); -void xen_refresh_vbd_list (struct task_struct *p); long vbd_create(vbd_create_t *create_info); long vbd_add(vbd_add_t *add_info); long vbd_remove(vbd_remove_t *remove_info); long vbd_delete(vbd_delete_t *delete_info); -/* Describes a physical disk extent (part of a block io request) */ + +/* Describes a [partial] disk extent (part of a block io request) */ typedef struct { unsigned short dev; unsigned short nr_sects; @@ -49,15 +49,4 @@ int vbd_translate(phys_seg_t * pseg, int *nr_segs, struct task_struct *p, int operation); -#if 0 -void destroy_physdisk_aces(struct task_struct *p); - -int xen_physdisk_grant(xp_disk_t *); -int xen_physdisk_probe(struct task_struct *requesting_task, - physdisk_probebuf_t *); -int xen_physdisk_access_okay(phys_seg_t *pseg, struct task_struct *p, - int operation); -#endif - - -#endif /* PHYSDISK_ACES__ */ +#endif /* __VBD_H__ */ diff --git a/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c b/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c index 40150a76ad..29619bbbc3 100644 --- a/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c +++ b/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c @@ -160,6 +160,7 @@ int xenolinux_block_ioctl(struct inode *inode, struct file *filep, return 0; } +/* check media change: should probably do something here in some cases :-) */ int xenolinux_block_check(kdev_t dev) { DPRINTK("xenolinux_block_check\n"); @@ -246,8 +247,6 @@ static int hypervisor_request(unsigned long id, switch ( operation ) { -// case XEN_BLOCK_PHYSDEV_GRANT: -// case XEN_BLOCK_PHYSDEV_PROBE: case XEN_BLOCK_PROBE: if ( RING_PLUGGED ) return 1; sector_number = 0; @@ -431,12 +430,6 @@ static void xlblk_response_int(int irq, void *dev_id, struct pt_regs *ptregs) } break; - case XEN_BLOCK_VBD_CREATE: - case XEN_BLOCK_VBD_DELETE: - case XEN_BLOCK_PHYSDEV_GRANT: - case XEN_BLOCK_PHYSDEV_PROBE: - printk(KERN_ALERT "response for bogus operation %d\n", - bret->operation); case XEN_BLOCK_PROBE: xlblk_control_msg_pending = bret->status; break; diff --git a/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_vbd.c b/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_vbd.c index 9656452c43..7a25020b39 100644 --- a/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_vbd.c +++ b/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_vbd.c @@ -77,7 +77,7 @@ typedef unsigned char bool; int __init xlvbd_init(xen_disk_info_t *xdi) { int i, result, nminors; - struct gendisk *gd; + struct gendisk *gd = NULL; kdev_t device; unsigned short major, minor, real_minor; bool is_ide, is_scsi; @@ -237,6 +237,9 @@ int __init xlvbd_init(xen_disk_info_t *xdi) majors[major] = 1; } + if(XD_READONLY(xdi->disks[i].info)) + set_device_ro(device, 1); + if(real_minor) { /* Need to skankily setup 'partition' information */ @@ -247,29 +250,28 @@ int __init xlvbd_init(xen_disk_info_t *xdi) } else { /* Some final fix-ups depending on the device type */ - switch (xdi->disks[i].type) + switch (XD_TYPE(xdi->disks[i].info)) { + case XD_TYPE_CDROM: - set_device_ro(device, 1); - case XD_TYPE_FLOPPY: case XD_TYPE_TAPE: gd->flags[0] = GENHD_FL_REMOVABLE; printk(KERN_ALERT "Skipping partition check on %s /dev/%s\n", - xdi->disks[i].type==XD_TYPE_CDROM ? "cdrom" : - (xdi->disks[i].type==XD_TYPE_TAPE ? "tape" : + XD_TYPE(xdi->disks[i].info)==XD_TYPE_CDROM ? "cdrom" : + (XD_TYPE(xdi->disks[i].info)==XD_TYPE_TAPE ? "tape" : "floppy"), disk_name(gd, MINOR(device), buf)); break; - + case XD_TYPE_DISK: register_disk(gd, device, gd->nr_real, &xlvbd_block_fops, xdi->disks[i].capacity); break; default: - printk(KERN_ALERT "XenoLinux: unknown ide device type %d\n", - xdi->disks[i].type); + printk(KERN_ALERT "XenoLinux: unknown device type %d\n", + XD_TYPE(xdi->disks[i].info)); break; } @@ -304,41 +306,36 @@ struct gendisk *xldev_to_gendisk(kdev_t xldev) void xlvbd_cleanup(void) { -#if 0 - if ( xlvbd_gendisk == NULL ) return; - - blk_cleanup_queue(BLK_DEFAULT_QUEUE(XLVIRT_MAJOR)); + bool is_ide, is_scsi; + struct gendisk *gd; + char *major_name; + int major; - xlvbd_gendisk = NULL; + for(major = 0; major < XLVBD_MAX_MAJORS; major++) { - read_ahead[XLVIRT_MAJOR] = 0; + if(!(gd = xlvbd_gendisk[major])) + continue; - if ( blksize_size[XLVIRT_MAJOR] != NULL ) - { - kfree(blksize_size[XLVIRT_MAJOR]); - blksize_size[XLVIRT_MAJOR] = NULL; - } + is_ide = IDE_DISK_MAJOR(major); /* is this an ide device? */ + is_scsi= SCSI_BLK_MAJOR(major); /* is this a scsi device? */ + + blk_cleanup_queue(BLK_DEFAULT_QUEUE(major)); + + if(is_ide) { + major_name = XLIDE_MAJOR_NAME; + } else if(is_scsi) { + major_name = XLSCSI_MAJOR_NAME; + } else { + major_name = XLVBD_MAJOR_NAME; + } + + if (unregister_blkdev(major, major_name) != 0) + printk(KERN_ALERT "XenoLinux Virtual Block Device Driver:" + "major device %04x uninstalled w/ errors\n", major); - if ( hardsect_size[XLVIRT_MAJOR] != NULL ) - { - kfree(hardsect_size[XLVIRT_MAJOR]); - hardsect_size[XLVIRT_MAJOR] = NULL; - } - - if ( max_sectors[XLVIRT_MAJOR] != NULL ) - { - kfree(max_sectors[XLVIRT_MAJOR]); - max_sectors[XLVIRT_MAJOR] = NULL; - } - - if ( unregister_blkdev(XLVIRT_MAJOR, XLVIRT_MAJOR_NAME) != 0 ) - { - printk(KERN_ALERT - "XenoLinux Virtual Block Device Driver" - " uninstalled w/ errs\n"); } -#endif - printk(KERN_ALERT "xlvbd_cleanup: not implemented XXX FIXME SMH\n"); + + return; } -- 2.30.2